from flask import Flask, render_template, request, jsonify, send_file
from datetime import datetime
import pandas as pd
import os
from logger_config import logger
from db_utils import db

app = Flask(__name__)

# 添加模板全局函数
@app.template_global()
def zip_items(*args):
    return zip(*args)

@app.route('/')
def index():
    """首页"""
    logger.info("访问首页")
    return render_template('index.html')

@app.route('/create', methods=['GET', 'POST'])
def create():
    """创建评分项页面"""
    if request.method == 'POST':
        try:
            # 检查是否是文件上传
            if 'file' in request.files:
                file = request.files['file']
                if file.filename == '':
                    return jsonify({'error': '未选择文件'}), 400
                
                if not file.filename.endswith('.xlsx'):
                    return jsonify({'error': '只支持 .xlsx 格式的文件'}), 400
                
                # 读取Excel文件
                df = pd.read_excel(file)
                
                # 验证数据格式
                required_columns = ['项目', '勾选项']
                if not all(col in df.columns for col in required_columns):
                    return jsonify({'error': 'Excel文件格式不正确，请使用模板文件'}), 400
                
                # 处理每一行数据
                for _, row in df.iterrows():
                    item_name = row['项目']
                    is_checkbox = row['勾选项'] == '是'
                    
                    # 提取选项和分数
                    options = []
                    scores = []
                    option_ids = [] # 新增
                    for i in range(1, 7):  # 假设最多6个选项
                        option_col = f'选项{i}'
                        score_col = f'分数{i}'
                        option_id_col = f'选项ID{i}' # 新增
                        if option_col in df.columns and score_col in df.columns and option_id_col in df.columns:
                            option = row[option_col]
                            score = row[score_col]
                            option_id = row[option_id_col] # 新增
                            if pd.notna(option) and pd.notna(score) and pd.notna(option_id): # 新增
                                options.append(str(option))
                                scores.append(int(score))
                                option_ids.append(int(option_id)) # 新增
                    
                    if options and scores:
                        db.add_judge_item(item_name, is_checkbox, option_ids, options, scores) # 修改
                
                return jsonify({'message': '导入成功'})
            
            # 处理JSON数据（手动创建）
            data = request.get_json()
            item_name = data.get('item_name')
            is_checkbox = data.get('is_checkbox')
            options = data.get('options')
            scores = data.get('scores')
            option_ids = data.get('option_ids')

            if not all([item_name, is_checkbox is not None, options, scores, option_ids]):
                return jsonify({'error': '所有字段都是必填的'}), 400

            # 将选项、分数、id打包为字典
            option_list = []
            for opt, score, oid in zip(options, scores, option_ids):
                option_list.append({'id': oid, 'option': opt, 'score': score})

            item_id = db.add_judge_item(item_name, is_checkbox, option_list)
            logger.info(f"创建新评分项: {item_name}, ID: {item_id}")
            return jsonify({'message': '创建成功', 'id': item_id})
        except Exception as e:
            logger.error(f"创建评分项失败: {str(e)}")
            return jsonify({'error': str(e)}), 500

    return render_template('create.html')

@app.route('/judge')
def judge():
    """评分页面"""
    try:
        logger.info("开始获取评分项列表")
        items = db.get_all_judge_items()
        logger.info(f"获取到的评分项数据: {items}")
        today = datetime.now()
        today_str = today.strftime('%Y-%m-%d')
        
        # 获取今日已提交的数据
        submitted_data = db.get_day_data(today_str)
        # 将已提交数据转换为以item_id为键的字典
        submitted_dict = {}
        if submitted_data:
            for item in submitted_data:
                submitted_dict[item['item_id']] = {
                    'selected_option': item['selected_option'],
                    'score': item['score']
                }
        
        logger.info(f"获取评分项列表，共 {len(items)} 项，已提交 {len(submitted_dict)} 项")
        return render_template('judge.html', items=items, today=today, submitted_data=submitted_dict)
    except Exception as e:
        logger.error(f"获取评分项失败: {str(e)}")
        logger.exception("详细错误信息：")
        return render_template('error.html', error=str(e))

@app.route('/submit', methods=['POST'])
def submit():
    """提交评分"""
    try:
        data = request.get_json()
        date = datetime.now().strftime('%Y-%m-%d')
        
        # 获取今日已提交的数据
        existing_data = db.get_day_data(date)
        existing_dict = {item['item_id']: item for item in existing_data} if existing_data else {}
        
        # 记录新提交的数据
        new_submissions = []
        
        for item in data:
            item_id = item.get('id')
            selected_option = item.get('selected_option')
            score = item.get('score')
            
            if not all([item_id, selected_option, score]):
                continue
                
            # 检查该项是否已提交
            if item_id in existing_dict:
                continue
                
            # 添加到新提交列表
            new_submissions.append({
                'item_id': item_id,
                'selected_option': selected_option,
                'score': score
            })
        
        # 如果有新提交的数据，则保存到数据库
        if new_submissions:
            for submission in new_submissions:
                db.add_day_data(date, submission['item_id'], submission['selected_option'], submission['score'])
            logger.info(f"提交评分成功，日期: {date}，新增 {len(new_submissions)} 项")
            return jsonify({'message': '提交成功'})
        else:
            return jsonify({'error': '没有新的评分项需要提交'}), 400
            
    except Exception as e:
        logger.error(f"提交评分失败: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/history')
def history():
    """历史记录页面"""
    try:
        date = request.args.get('date', datetime.now().strftime('%Y-%m-%d'))
        data = db.get_day_data(date)
        logger.info(f"获取历史记录，日期: {date}")
        return render_template('history.html', data=data, date=date)
    except Exception as e:
        logger.error(f"获取历史记录失败: {str(e)}")
        return render_template('error.html', error=str(e))

@app.route('/api/history')
def get_history():
    """获取历史记录API"""
    try:
        date = request.args.get('date', datetime.now().strftime('%Y-%m-%d'))
        data = db.get_day_data(date)
        logger.info(f"API获取历史记录，日期: {date}")
        return jsonify(data)
    except Exception as e:
        logger.error(f"API获取历史记录失败: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/static/template.xlsx')
def download_template():
    try:
        logger.info('开始生成Excel模板文件')
        # 创建示例数据
        data = {
            '项目': ['睡觉时间', '运动时间'],
            '勾选项': ['是', '否'],
            '选项1': ['<9:30', '0分钟'],
            '选项2': ['10:00', '30分钟'],
            '选项3': ['10:30', '1小时'],
            '选项4': ['11:00', '1.5小时'],
            '选项5': ['>11:00', '2小时'],
            '选项6': ['>12:00', '>2小时'],
            '分数1': [10, 0],
            '分数2': [8, 5],
            '分数3': [6, 8],
            '分数4': [3, 10],
            '分数5': [0, 12],
            '分数6': [-5, 15]
        }
        
        # 确保目录存在
        os.makedirs('static', exist_ok=True)
        
        # 生成Excel文件
        df = pd.DataFrame(data)
        template_path = os.path.join('static', 'template.xlsx')
        df.to_excel(template_path, index=False)
        
        logger.info('Excel模板文件生成成功')
        return send_file(template_path, as_attachment=True)
    except Exception as e:
        logger.error(f'生成Excel模板文件时发生错误: {str(e)}')
        return jsonify({'error': str(e)}), 500

@app.route('/manage')
def manage():
    """评分项管理页面"""
    try:
        items = db.get_all_judge_items(include_disabled=True)
        return render_template('manage.html', items=items)
    except Exception as e:
        logger.error(f"获取评分项列表失败: {str(e)}")
        return render_template('error.html', error=str(e))

@app.route('/api/items/status', methods=['POST'])
def update_items_status():
    """更新评分项状态"""
    try:
        data = request.get_json()
        item_ids = data.get('item_ids', [])
        enabled = data.get('enabled', True)
        
        if not item_ids:
            return jsonify({'error': '未选择评分项'}), 400
            
        if db.update_items_status(item_ids, enabled):
            return jsonify({'message': '更新成功'})
        else:
            return jsonify({'error': '更新失败'}), 500
    except Exception as e:
        logger.error(f"更新评分项状态失败: {str(e)}")
        return jsonify({'error': str(e)}), 500

@app.route('/api/items/delete', methods=['POST'])
def delete_items():
    """删除评分项"""
    try:
        data = request.get_json()
        item_ids = data.get('item_ids', [])
        
        if not item_ids:
            return jsonify({'error': '未选择评分项'}), 400
            
        if db.delete_items(item_ids):
            return jsonify({'message': '删除成功'})
        else:
            return jsonify({'error': '删除失败'}), 500
    except Exception as e:
        logger.error(f"删除评分项失败: {str(e)}")
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    try:
        db.init_db()
        logger.info("数据库初始化成功")
        app.run(host='0.0.0.0', port=5000, debug=True)
    except Exception as e:
        logger.error(f"应用启动失败: {str(e)}") 